/*  -------------------------- (C) COPYRIGHT 2022 Fortiortech ShenZhen ---------------------------*/
/**
 * @copyright (C) COPYRIGHT 2022 Fortiortech Shenzhen
 * @file      xxx.c
 * @author    Fortiortech  Appliction Team
 * @since     Create:2022-07-14
 * @date      Last modify:2022-07-14
 * @note      Last modify author is Leo.li
 * @brief
 */

/* Includes -------------------------------------------------------------------------------------*/
#include <FU68xx_2.h>
#include <Myproject.h>

/* Private variables ----------------------------------------------------------------------------*/
MotStaType data mcState;
MotStaM McStaSet;

/**
 * @brief     电机控制状态机
 * @warning   电机的状态只能在电机状态控制中切换，禁止在其他地方切换电机状态
 * @date      2022-07-14
 */
void MC_Control(void)
{
    if (mcFaultSource != FaultNoSource)
    {
        mcState = mcFault;
    }

    /* -----留意，最好不要在RUN中进行删除, 有通信时，确认时序,目前在电压正常时再进行擦除----- */
    if ((FlashData.Flag_FlashErase) && (mcFocCtrl.mcDcbusFlt > UNDER_RECOVER_VALUE))
    {
        Flash_Erase();
        FlashData.Flag_FlashErase = 0;
    }

    switch (mcState)
    {
    case mcReady: // 关闭输出,上电会对电流进行采集校准,当采样校准结束标志置1且启动指令置1后，才跳转到mcInit
        Motor_Ready();

        if ((mcCurOffset.OffsetFlag == 1) && (MCCtrl.FlagONOFF == 1))
        {
            mcState = mcInit;
            mcCurOffset.OffsetFlag = 0;  // 开始电流采集
            mcCurOffset.OffsetCount = 0; // 清采样计数
            KS.ChangeKeyFlg = 1;         // LED显示
        }

        break;

    case mcInit: // 初始化状态，进入mcCharge状态
        if (mcCurOffset.OffsetFlag == 1)
        {
            Motor_Init();
            mcState = mcCharge; // 跳入mcCharge状态
            mcFocCtrl.State_Count = Charge_Time;
        }

        break;

    case mcCharge: // 预充电状态，MCU输出固定频率占空比，预充电结束后，跳入mcTailWind
        Motor_Charge();
#if (IPMState == NormalRun) // 正常按电机状态机运行
        {
            if (mcFocCtrl.State_Count == 0)
            {
                MOE = 0; // 关闭输出
                mcState = mcTailWind;
                mcFocCtrl.State_Count = 0;
            }
        }
#endif
        break;

    case mcTailWind:
        Motor_TailWind();
        break;

    case mcPosiCheck:
#if (PosCheckEnable == 0) // 初始位置检测不使能时初始角度为预定位角度
        mcFocCtrl.mcPosCheckAngle = Align_Angle;
        mcState = mcAlign;
        mcFocCtrl.State_Count = Align_Time;
#else
        RPD();

        if (mcFocCtrl.State_Count == 0) // RPD每拍执行时间
        {
            if (RPD_Status != RPD_7)
            {
                MOE = 1;                // 打开MOE
                SetBit(TIM2_CR1, T2EN); // 启动TIM2,确保每拍使能的时间相同
            }
            else
            {
                DRV_CMR &= 0xFFC0;
                mcFocCtrl.mcPosCheckAngle = _Q15((float)RPDPara.ThetaGet / 180.0);
                mcState = mcAlign;
                mcFocCtrl.State_Count = Align_Time;
                /******************************
                    0: 正常模式，DAC输出电压范围为0到VREF，适用于硬件过流保护
                    1: 半电压转换模式，DAC输出电压范围为VHALF到VREF
                ****************************/
                ClrBit(DAC_CR, DACMOD);
                /**********设置DAC过流值*****************/
                DAC_DR = DAC_OvercurrentValue;
            }

            ClrBit(TIM2_CR1, T2EN);           // 关闭TIM2
            TIM2__CNTR = 0;                   // TIM2计数值清零
            RPD_Inject();                     // RPD注入的时序及角度判断
            mcFocCtrl.State_Count = RPD_Time; // RPD每拍执行时间
        }

#endif
        break;

    case mcAlign: // 预定位时间结束后，直接启动; AlignTestMode=1用于初始位置检测调试用
        Motor_Align();
#if (AlignTestMode == 1)

        while (1)
            ;

#else

        if (mcFocCtrl.State_Count == 0)
        {
            mcState = mcStart;
            ClrBit(FOC_CR2, UQD);
            User.TPCtrlDealy = 5000; // 延时启动发热
        }

#endif
        break;

    case mcStart: // 配置电机启动参数，进入mcRun状态。
        Motor_Open();
        mcState = mcRun;
        break;

    case mcRun: // 运行状态，若运行状态的给定变为0，进入mcStop状态。
        if (MCCtrl.FlagONOFF == 0)
        {
            mcState = mcStop;
            mcFocCtrl.State_Count = 200;
            FOC_IQREF = 0;
        }

        break;

    case mcStop:
        MC_Stop();
        break;

    case mcBrake:
        if (mcFocCtrl.State_Count == 0)
        {
            MCCtrl.FlagFR = 0;
            MOE = 0;
            ClrBit(DRV_CR, FOCEN);
            mcState = mcReady;
        }

        break;

    case mcFault:
        if (mcFaultSource == FaultUnderVoltage)
        {
            UnderProcess(); // 欠压保护处理函数
            if (KS.KeyValuetotalInit != (KS.KeyValuetotal & 0x8F))
                Save_KeyValue(); // 保存按键值
        }
        else
        {
            FaultProcess();

            if (mcFaultSource == FaultNoSource)
            {
                mcState = mcReady;
            }
        }

        break;

    default:
        mcState = mcReady;
        break;
    }
}
